package com.hsy.crm.web.service.impl;

import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.Order;
import com.hsy.crm.web.domain.entity.ReceiptOrder;
import com.hsy.crm.web.domain.entity.ReceiptOrderAccount;
import com.hsy.crm.web.domain.entity.ReceiptOrderOrder;
import com.hsy.crm.web.domain.po.receiptOrder.ReceiptOrderOrderPagePo;
import com.hsy.crm.web.domain.po.receiptOrder.ReceiptOrderPagePo;
import com.hsy.crm.web.domain.po.receiptOrder.ReceiptOrderPo;
import com.hsy.crm.web.domain.vo.receiptOrder.ReceiptInsertVo;
import com.hsy.crm.web.domain.vo.receiptOrder.ReceiptOrderOrderPageVo;
import com.hsy.crm.web.domain.vo.receiptOrder.ReceiptOrderPageVo;
import com.hsy.crm.web.mapper.OrderMapper;
import com.hsy.crm.web.mapper.ReceiptOrderAccountMapper;
import com.hsy.crm.web.mapper.ReceiptOrderMapper;
import com.hsy.crm.web.mapper.ReceiptOrderOrderMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.ListUtils;
import com.hsy.crm.web.utils.UuidUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ReceiptOrderService extends BaseService<ReceiptOrder> {

    @Autowired
    AccountService accountService;

    @Autowired
    ReceiptOrderMapper receiptOrderMapper;

    @Autowired
    ReceiptOrderOrderMapper receiptOrderOrderMapper;

    @Autowired
    ReceiptOrderAccountMapper receiptOrderAccountMapper;

    @Autowired
    OrderMapper orderMapper;

    @Transactional
    public Unified<Integer> examine(ReceiptOrder order) {
        ReceiptOrder dbOrder = receiptOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        return this.updateStatus(dbOrder,App.Status.SH);
    }

    @Transactional
    public Unified<Integer> doInvalid(ReceiptOrder order) {
        ReceiptOrder dbOrder = receiptOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        return this.updateStatus(dbOrder,App.Status.BC);
    }

    @Transactional
    public Unified<ReceiptOrder> insertReceiptOrder(ReceiptInsertVo vo) {
        Unified<ReceiptOrder> unified = new Unified<>();

        ReceiptOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        order.setStatus(App.Status.BC);
        order.setLoginUserId(vo.getLoginUserId());
        order.setLoginCompanyId(vo.getLoginCompanyId());
        order.setCode(DataInitService.getOrderCode());
        order.setVerificateMoney(0L);
        this.insert(order);

        insertAccounts(vo);
        insertOrderOrders(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            examine(order);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<ReceiptOrder> updateReceiptOrder(ReceiptInsertVo vo) {
        Unified<ReceiptOrder> unified = new Unified<>();

        ReceiptOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        order.setLoginUserId(vo.getLoginUserId());
        order.setLoginCompanyId(vo.getLoginCompanyId());
        this.update(order);

        deleteAccounts(order);
        insertAccounts(vo);
        deleteOrderOrders(order);
        insertOrderOrders(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            examine(order);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> deleteReceiptOrder(ReceiptOrder receiptOrder) {

        Unified<Integer> unified = new Unified<>();

        this.deleteAccounts(receiptOrder);
        this.deleteOrderOrders(receiptOrder);

        ReceiptOrder deleteOrder = new ReceiptOrder();
        deleteOrder.setCustomerId(receiptOrder.getCustomerId());
        deleteOrder.setId(receiptOrder.getId());
        receiptOrderMapper.delete(deleteOrder);

        return unified;

    }

    public PageResult<ReceiptOrderPagePo> page(ReceiptOrderPageVo receiptOrderPageVo) {
        Page page = PageHelper.startPage(receiptOrderPageVo.getPage(),receiptOrderPageVo.getLimit());
        PageResult<ReceiptOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(receiptOrderMapper.page(receiptOrderPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public PageResult<ReceiptOrderOrderPagePo> orderPage(ReceiptOrderOrderPageVo vo) {
        Page page = PageHelper.startPage(vo.getPage(),vo.getLimit());
        PageResult<ReceiptOrderOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(receiptOrderMapper.orderPage(vo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public Unified<ReceiptOrderPo> getOrder(ReceiptOrder receiptOrder) {
        Unified<ReceiptOrderPo> unified = new Unified<>();

        ReceiptOrderPo po = new ReceiptOrderPo();
        po.setOrder(receiptOrderMapper.getOrder(receiptOrder));
        po.setAccounts(receiptOrderMapper.getOrderAccounts(receiptOrder));
        po.setOrderOrders(receiptOrderMapper.getOrderOrders(receiptOrder));

        unified.setData(po);
        return unified;
    }

    public void updateOrderVerificateMoney(String customerId,Long orderId,Long verificateMoney){
        Order dbOrder = new Order();
        dbOrder.setId(orderId);
        dbOrder.setCustomerId(customerId);
        dbOrder = orderMapper.selectByPrimaryKey(dbOrder);
        Order order = new Order();
        //订单金额
        long dueMoney = dbOrder.getDueMoney();
        //优惠金额
        long discountMoney = dbOrder.getDiscountMoney();
        //已收金额
        long realMoney = dbOrder.getRealMoney();
        if( discountMoney + realMoney + verificateMoney + dbOrder.getVerificateMoney() == dueMoney ){
            order.setStatus(App.StatusDD.QK);
        }else{
            order.setStatus(App.StatusDD.BFK);
        }

        order.setId(orderId);
        order.setVerificateMoney(verificateMoney);
        order.setCustomerId(customerId);
        receiptOrderMapper.updateOrderVerificate(order);
    }

    private void insertAccounts(ReceiptInsertVo vo){
        for ( ReceiptOrderAccount account : vo.getAccounts() ){
            account.setReceiptOrderId(vo.getOrder().getId());
            account.setId(UuidUtils.getUuid());
            account.setCustomerId(vo.getCustomerId());
            if( account.getRemarks() == null ) account.setRemarks(App.DbDefaultValue.CHAR);
            receiptOrderAccountMapper.insert(account);
        }
    }

    private void deleteAccounts(ReceiptOrder order){
        ReceiptOrderAccount account = new ReceiptOrderAccount();
        account.setReceiptOrderId(order.getId());
        account.setCustomerId(order.getCustomerId());
        receiptOrderAccountMapper.delete(account);
    }

    private void deleteOrderOrders(ReceiptOrder order){
        ReceiptOrderOrder orderOrder = new ReceiptOrderOrder();
        orderOrder.setReceiptOrderId(order.getId());
        orderOrder.setCustomerId(order.getCustomerId());
        receiptOrderOrderMapper.delete(orderOrder);
    }

    private void insertOrderOrders(ReceiptInsertVo vo){
        if(ListUtils.isNotEmpty(vo.getVerificates())){
            for ( ReceiptOrderOrder verificate : vo.getVerificates() ){
                verificate.setReceiptOrderId(vo.getOrder().getId());
                verificate.setId(UuidUtils.getUuid());
                verificate.setCustomerId(vo.getCustomerId());
                receiptOrderOrderMapper.insert(verificate);
            }
        }

    }

    private Unified<Integer> updateStatus(ReceiptOrder order,int status){
        Unified<Integer> unified = new Unified<>();

        ReceiptOrder updateOrder = new ReceiptOrder();
        updateOrder.setId(order.getId());
        updateOrder.setCustomerId(order.getCustomerId());
        updateOrder.setStatus(status);
        receiptOrderMapper.updateByPrimaryKeySelective(updateOrder);

        this.updateAccounts(order,status);

        this.updateOrderOrders(order,status);

        return unified;
    }

    private void updateOrderOrders(ReceiptOrder order,int status){
        ReceiptOrderOrder orderOrder = new ReceiptOrderOrder();
        orderOrder.setCustomerId(order.getCustomerId());
        orderOrder.setReceiptOrderId(order.getId());
        List<ReceiptOrderOrder> orderOrders = receiptOrderOrderMapper.select(orderOrder);
        for( ReceiptOrderOrder ordord : orderOrders ){
            if( order.getType() == 1 ){
                if( status == App.Status.SH ){
                    updateOrderVerificateMoney(order.getCustomerId(),ordord.getTargetId(),ordord.getVerificateMoney());
                }else if( status == App.Status.BC ){
                    updateOrderVerificateMoney(order.getCustomerId(),ordord.getTargetId(),-ordord.getVerificateMoney());
                }
            }else{
                if( status == App.Status.SH ){
                    updateOrderVerificateMoney(order.getCustomerId(),ordord.getTargetId(),ordord.getVerificateMoney());
                }else if( status == App.Status.BC ){
                    updateOrderVerificateMoney(order.getCustomerId(),ordord.getTargetId(),-ordord.getVerificateMoney());
                }
            }
        }
    }

    private void updateAccounts(ReceiptOrder order,int status){
        ReceiptOrderAccount account = new ReceiptOrderAccount();
        account.setCustomerId(order.getCustomerId());
        account.setReceiptOrderId(order.getId());
        List<ReceiptOrderAccount> accounts = receiptOrderAccountMapper.select(account);
        for (ReceiptOrderAccount acct : accounts){
            accountService.updateBalance(order.getCustomerId(),acct.getAccountId(),acct.getReceiptMoney(),getDirection(order.getType(),status));
        }
    }

    private int getDirection(int type,int status){
        if( type == 1 ){
            if( status == App.Status.SH ){
                return App.Direction.ADD;
            }else if( status == App.Status.BC ){
                return App.Direction.SUB;
            }
        }else{
            if( status == App.Status.SH ){
                return App.Direction.SUB;
            }else if( status == App.Status.BC ){
                return App.Direction.ADD;
            }
        }

        return -1;
    }



}
